import React, { Component } from 'react';
import PropTypes from 'prop-types';
import { Button, Form, Field, Message, Balloon } from '@teamix/ui';
import FormItemSwitch from 'atComponents/FormItemSwitch';
import BalloonConfirm from 'components/ballonConfirm';
import { ORGANIZATION_ADMIN_ROLES } from 'utils/constants.js';
import { getPathWithRootPath } from 'utils/router';
import { getFeature } from 'utils/features';
import DeletePathResourceDialog from 'components/deletePathResourceDialog';
import debounce from 'lodash.debounce';
import { checkProjectName, checkCanTranfer } from 'api/index.js';
import { access } from 'components/accessContainer/util';
import AddonBeforeInput from 'components/addonBeforeInput';
import GroupSelect from 'components/groupSelect';
import intl from '../../../../../../../../../../locale';

const { Tooltip } = Balloon;

// id通过force取得
const { pathResource, organization } = window.FORCE;
const { user_role } = organization;

const FormItem = Form.Item;

export default class DangerousForm extends Component {
  static propTypes = {
    searchNamespaces: PropTypes.func,
    archiveOrUnarchive: PropTypes.func,
    transfer: PropTypes.func,
    rename: PropTypes.func,
    name: PropTypes.string,
    path: PropTypes.string,
    fullName: PropTypes.string,
    httpUrl: PropTypes.string,
    removeConfirmVisible: PropTypes.bool,
    removeConfirmContent: PropTypes.string,
    removeButtonDisabled: PropTypes.bool,
    isArchived: PropTypes.bool,
    isRemoving: PropTypes.bool,
    isTransferring: PropTypes.bool,
    remove: PropTypes.func,
  };

  static defaultProps = {
    archiveOrUnarchive: () => {},
    transfer: () => {},
    searchNamespaces: () => {},
    rename: () => {},
    remove: () => {},
    name: '',
    path: '',
    fullName: '',
    httpUrl: '',
    removeConfirmVisible: false,
    removeConfirmContent: null,
    removeButtonDisabled: true,
    isArchived: false,
    isRemoving: false,
    isTransferring: false,
  };

  constructor(props) {
    super(props);
    this.renameField = new Field(this);
    this.transferField = new Field(this);
    this.state = {
      namespaces: [],
      // 将要转移移到的代码组ID
      target_id: '',
      target_path: '',
    };

    this.checkPath = debounce(this.checkPath, 500);
    this.onNamespaceSearch = debounce(this.onNamespaceSearch.bind(this), 500);
  }

  componentDidMount() {
    // 获取企业下拉数据
    this.props.searchNamespaces('', (result) => {
      const { list } = result;
      this.setState({ namespaces: list });
    });
    this.props.getRepoSettingData();
  }

  onNamespaceSearch(value) {
    this.props.searchNamespaces(value, (result) => {
      this.setState({ namespaces: result.list });
    });
  }

  getPathPrefix = (httpUrl) => {
    return httpUrl ? `${httpUrl.match(/(.+)\/.+\.git/)[1]}/` : httpUrl;
  };

  getNewFullPath = (httpUrl) => {
    const prefix = httpUrl ? `${httpUrl.match(/(.+)\/.+\.git/)[1]}/` : httpUrl;
    const path = this.renameField.getValue('path');
    return prefix + path;
  };

  checkPath(value, callback) {
    checkProjectName({ path: value })
      .then(() => {
        callback();
      })
      .catch((err) => {
        if (err.responseText) {
          const errCause = JSON.parse(err.responseText).message;
          callback(errCause);
        } else {
          throw err;
        }
      });
  }

  pathValidator = (rule, value, callback) => {
    const { path } = this.props;
    if (!value || value === path) {
      callback();
      return;
    }
    if (/^[a-zA-Z0-9_.][a-zA-Z0-9_.-]{0,}$/.test(value)) {
      this.checkPath(value, callback);
    } else {
      callback(
        intl.get({
          id: 'code-assets.containers.dagenrousForm.ItCanOnlyContainLetters',
          defaultMessage: "只能包含字母和数字、 '_'、 '.'和'-'，且只能以字母、数字或'_'开头",
        }),
      );
    }
  };

  namespaceValidator = (rule, value, callback) => {
    checkCanTranfer({
      namespace_id: value,
      project_id: pathResource.id,
    })
      .then(() => {
        callback();
      })
      .catch((err) => {
        if (err.responseText) {
          const errCause = JSON.parse(err.responseText).cause;
          callback(`${errCause}`);
        } else {
          throw err;
        }
      });
  };

  rename = (cb) => {
    this.renameField.validate((errors) => {
      if (!errors) {
        const formData = this.renameField.getValues();
        formData.name = this.props.name;
        this.props.rename(formData, (data) => {
          cb(data);
        });
      }
    });
  };

  archiveOrUnarchive = () => {
    this.props.archiveOrUnarchive(!this.props.isArchived);
  };

  transfer = (callback) => {
    const { target_id, target_path } = this.state;
    if (!target_id) {
      Message.warning({
        title: intl.get({
          id: 'code-assets.containers.dagenrousForm.SelectACodeGroup',
          defaultMessage: '请选择代码组',
        }),
      });

      return;
    }
    this.props.transfer({ groupId: target_id, path_with_namespace: target_path }, callback);
  };

  setSelectNamespace = (item) => {
    const { path } = this.props;
    this.setState({
      target_id: item.value ? Number(item.value) : organization.namespace_id,
      target_path: `${item.path_with_namespace}/${path}`,
    });
  };

  render() {
    const {
      path,
      httpUrl,
      isArchived,
      name,
      repoAdminOperation = [],
      is_crypto_enabled,
    } = this.props;
    const renameInit = this.renameField.init;
    const transferInit = this.transferField.init;
    const { namespaces, target_path } = this.state;
    const namespaceDatabase = [];

    namespaces.forEach((item) => {
      item.id !== Number(organization.id) &&
        namespaceDatabase.push({
          label: item.name,
          value: item.path,
        });
    });

    const { fullPath } = pathResource;
    const curPath = fullPath.split('/')[1];
    const pathChange = curPath !== this.renameField.getValue('path');
    const transferDisabled =
      !this.transferField.getValue('namespace_id') ||
      this.transferField.getValue('namespace_id') === Number(pathResource.parentId) ||
      this.transferField.getError('namespace_id') !== null;

    const newFullPath = this.getNewFullPath(httpUrl);
    const projectName = name;
    let repoAdminDelRepo = false;
    repoAdminOperation &&
      repoAdminOperation.forEach((val) => {
        if (val === 1) {
          repoAdminDelRepo = true;
        }
      });
    return (
      <>
        <FormItemSwitch
          title={intl.get({
            id: 'code-assets.containers.dagenrousForm.CodeLibraryPathModification',
            defaultMessage: '代码库路径修改',
          })}
          description={intl.get({
            id: 'code-assets.containers.dagenrousForm.TheNameAndPathOf',
            defaultMessage:
              '代码库的名称和路径是不同的概念，会影响开发人员实际操作及访问，导致原克隆地址不可用',
          })}
        >
          <Form inline field={this.renameField}>
            <FormItem label="" className="no-mr-b">
              <AddonBeforeInput
                addonTextBefore={this.getPathPrefix(httpUrl)}
                {...renameInit('path', {
                  initValue: path,
                  rules: [
                    {
                      required: true,
                      message: intl.get({
                        id: 'code-assets.containers.dagenrousForm.ThisParameterIsRequired',
                        defaultMessage: '该项为必填项',
                      }),
                    },

                    {
                      validator: this.pathValidator,
                    },
                  ],
                })}
                placeholder={intl.get({
                  id: 'code-assets.containers.dagenrousForm.EnterTheCodeLibraryPath',
                  defaultMessage: '请输入代码库路径',
                })}
                className="path-input"
              />
            </FormItem>
            <FormItem label="" className="no-mr-b">
              {pathChange ? (
                <BalloonConfirm
                  type="warning"
                  align="br"
                  title={intl.get({
                    id: 'code-assets.containers.dagenrousForm.ConfirmModification',
                    defaultMessage: '确认修改',
                  })}
                  content={intl.get(
                    {
                      id: 'code-assets.containers.dagenrousForm.ConfirmThatThePathOf',
                      defaultMessage: '确认修改库路径为 {newFullPath}',
                    },
                    { newFullPath },
                  )}
                  triggerType="click"
                  size="large"
                  trigger={
                    <Button type="primary" warning style={{ display: 'inline-block' }}>
                      {intl.get({
                        id: 'code-assets.containers.dagenrousForm.Modify',
                        defaultMessage: '修改',
                      })}
                    </Button>
                  }
                  okFn={this.rename}
                  followTrigger
                />
              ) : (
                <Button type="primary" warning disabled style={{ display: 'inline-block' }}>
                  {intl.get({
                    id: 'code-assets.containers.dagenrousForm.Modify',
                    defaultMessage: '修改',
                  })}
                </Button>
              )}
            </FormItem>
          </Form>
        </FormItemSwitch>
        {getFeature('project.setting.project_transfer') && (
          <FormItemSwitch
            title={intl.get({
              id: 'code-assets.containers.dagenrousForm.TransferCodeLibrary',
              defaultMessage: '转移代码库',
            })}
            description={intl.get({
              id: 'code-assets.containers.dagenrousForm.TransferringTheCodeLibraryAffects',
              defaultMessage:
                '转移代码库会影响开发人员实际操作及访问，导致源克隆地址不可用。转移后，需要更新本地仓库地址，指向新的地址',
            })}
          >
            <Form inline field={this.transferField}>
              <FormItem label="" className="no-mr-b">
                <GroupSelect
                  okFn={this.setSelectNamespace}
                  style={{ width: '320px', height: '40px' }}
                  // 这是代码库设置中的转移代码组部分
                  autoWidth
                  isFilterSelf
                  operateType={'transfer'}
                  type={'repo'}
                  popupProps={{
                    // 空库时和组一样，align居中
                    align: window.FORCE.pathResource.isEmpty === 'true' ? 'cc cc' : 'tl bl',
                  }}
                  {...transferInit('namespace_id', {
                    rules: [
                      {
                        validator: this.namespaceValidator,
                      },
                    ],
                  })}
                  isTransfer
                />
              </FormItem>
              <FormItem label="" className="no-mr-b">
                {!transferDisabled ? (
                  <BalloonConfirm
                    type="warning"
                    align="tl"
                    title={intl.get({
                      id: 'code-assets.containers.dagenrousForm.ConfirmTransfer',
                      defaultMessage: '确认转移',
                    })}
                    content={`确认要转移到 ${window.location.origin}${getPathWithRootPath(
                      target_path,
                    )} 吗？`}
                    triggerType="click"
                    size="large"
                    trigger={
                      <Button type="primary" warning style={{ display: 'inline-block' }}>
                        {intl.get({
                          id: 'code-assets.containers.dagenrousForm.Transfer',
                          defaultMessage: '转移',
                        })}
                      </Button>
                    }
                    okFn={this.transfer}
                    followTrigger
                  />
                ) : (
                  <Button type="primary" warning disabled style={{ display: 'inline-block' }}>
                    {intl.get({
                      id: 'code-assets.containers.dagenrousForm.Transfer',
                      defaultMessage: '转移',
                    })}
                  </Button>
                )}
              </FormItem>
            </Form>
          </FormItemSwitch>
          )
        }
        <FormItemSwitch
          title={intl.get({
            id: 'code-assets.containers.dagenrousForm.ArchiveCodeLibrary',
            defaultMessage: '代码库归档',
          })}
          description="代码库归档后，将限制为只读，且不支持在报表中使用"
          verticalMode
        >
          <BalloonConfirm
            type="warning"
            align="br"
            size="large"
            title={
              isArchived
                ? intl.get({
                    id: 'code-assets.containers.dagenrousForm.ConfirmUnarchiving',
                    defaultMessage: '确认解除归档',
                  })
                : intl.get({
                    id: 'code-assets.containers.dagenrousForm.ConfirmArchiving',
                    defaultMessage: '确认归档',
                  })
            }
            content={
              isArchived
                ? intl.get(
                    {
                      id: 'code-assets.containers.dagenrousForm.AreYouSureYouWant.1',
                      defaultMessage: '确认需要将代码库 {projectName} 解除归档吗？',
                    },
                    { projectName },
                  )
                : intl.get(
                    {
                      id: 'code-assets.containers.dagenrousForm.AreYouSureYouWant.2',
                      defaultMessage: '确认需要将代码库 {projectName} 归档吗？',
                    },
                    { projectName },
                  )
            }
            okFn={this.archiveOrUnarchive}
            triggerType="click"
            trigger={
              <Button type="primary" warning>
                {isArchived
                  ? intl.get({
                      id: 'code-assets.containers.dagenrousForm.Unarchive',
                      defaultMessage: '解除归档',
                    })
                  : intl.get({
                      id: 'code-assets.containers.dagenrousForm.Archive',
                      defaultMessage: '归档',
                    })}
              </Button>
            }
            followTrigger
          />
        </FormItemSwitch>
        <FormItemSwitch
          title={intl.get({
            id: 'code-assets.containers.dagenrousForm.DeleteACodeLibrary',
            defaultMessage: '删除代码库',
          })}
          description={intl.get({
            id: 'code-assets.containers.dagenrousForm.TheCodeLibraryWillBe',
            defaultMessage:
              '代码库将移入回收站，数据最长保留15天，此期间支持手动恢复，超期后数据将彻底删除，彻底删除后不可恢复',
          })}
          verticalMode
        >
          {is_crypto_enabled ||
          (!access(ORGANIZATION_ADMIN_ROLES, user_role) && !repoAdminDelRepo) ? (
            <Tooltip
              trigger={
                <Button type="primary" warning disabled>
                  {intl.get({
                    id: 'code-assets.containers.dagenrousForm.Delete',
                    defaultMessage: '删除',
                  })}
                </Button>
              }
              align="tl"
            >
              {is_crypto_enabled
                ? intl.get({
                    id: 'code-assets.containers.dagenrousForm.TheCurrentRepositoryIsEncrypted',
                    defaultMessage: '当前仓库已加密，暂不允许删除，请关闭「仓库加密」后再试',
                  })
                : intl.get({
                    id: 'code-assets.containers.dagenrousForm.TheEnterpriseRestrictionLibraryAdministrator',
                    defaultMessage: '企业限制库管理员删除代码库，请联系企业管理员处理',
                  })}
            </Tooltip>
          ) : (
            <DeletePathResourceDialog
              type={'repo'}
              name={name}
              trigger={
                <Button type="primary" warning>
                  {intl.get({
                    id: 'code-assets.containers.dagenrousForm.Delete',
                    defaultMessage: '删除',
                  })}
                </Button>
              }
            />
          )}
        </FormItemSwitch>
      </>
    );
  }
}
